home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / BG_SRC.ZIP / BG_DOUBL.C < prev    next >
C/C++ Source or Header  |  1993-12-31  |  8KB  |  291 lines

  1. /*
  2.  *                        B G _ D O U B L . C
  3.  * This module handles whether doubling and rejection of doubles
  4.  * O.F.Ransen:     7th January   1993
  5.  * This version:   31st December 1993
  6.  *
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <conio.h>
  12. #include "mousy.h"
  13. #include "bg.h"
  14.  
  15. /*************************************************************************/
  16.  
  17. int      Target_Score     = 3 ;
  18. int      Double_Value     = 1 ;
  19. Player_t Double_Possessor = NULL_PLAYER ;
  20. boolean  No_Cube          = FALSE ;
  21. int      N_Moves          = 0 ;
  22.  
  23. const double Pips_Per_Throw = 8.75 ;
  24.  
  25. static boolean Can_Double (Player_t Player) ;
  26. static boolean Selected_Double_Button (short x, short y) ;
  27.  
  28. /*************************************************************************/
  29.  
  30. boolean Human_Doubles (Player_t Player)
  31. /*
  32. PURPOSE: To wait until the mouse is clicked, inside or outside the
  33.          doubling button. We wait only if doubling is allowed.
  34. */
  35. {
  36.     if (Can_Double (Player)) {
  37.  
  38.         short   User_Input,x,y ;
  39.         boolean Finished ;
  40.         extern  boolean F10_Hit ;
  41.  
  42.         Print_Message (DBL_MSG) ;
  43.         Show_Mouse_Cursor () ;
  44.         Set_Cursor_Shape (QUESTION_SHP,0,0) ;
  45.  
  46.         Finished = FALSE ;
  47.         do {
  48.             User_Input = Get_Mouse_Or_Key (&x,&y) ;
  49.             if (User_Input & (LEFT_BIT | RIGHT_BIT)) {
  50.                 Finished = TRUE ;
  51.             } else if (User_Input & FUN_BIT) {
  52.                 if ((User_Input & CHAR_MASK) == F10_KEY) {
  53.                     Hide_Mouse_Cursor () ;
  54.                     F10_Hit = TRUE ;
  55.                     return (FALSE) ;
  56.                 }
  57.             }
  58.         } while (!Finished) ;
  59.  
  60.         Hide_Mouse_Cursor () ;
  61.  
  62.         return (Selected_Double_Button (x,y)) ;
  63.  
  64.     } else {
  65.         return (FALSE) ;
  66.     }
  67. }
  68.  
  69. /*************************************************************************/
  70.  
  71. static boolean Can_Double (Player_t Player)
  72. /*
  73. PURPOSE: To return TRUE if the player is allowed to double.
  74. */
  75. {
  76.     if ((Double_Possessor != Player) && (Double_Possessor != NULL_PLAYER)) {
  77.         return (FALSE) ;
  78.     } else if (Double_Value >= 32) {
  79.         /* Cannot go beyond this value */
  80.         return (FALSE) ;
  81.     } else if (No_Cube) {
  82.         return (FALSE) ;
  83.     } else {
  84.         return (TRUE) ;
  85.     }
  86. }
  87.  
  88. /*************************************************************************/
  89.  
  90. static boolean Selected_Double_Button (short x, short y)
  91. /*
  92. PURPOSE: To return TRUE if the player doubled by clicking inside
  93.          the doubling box, and if it was legal to do so.
  94. */
  95. {
  96.     extern Screen_Const_t Grafs ;
  97.     if ((x >= Grafs.Double_X) && (x <= (Grafs.Double_X + Grafs.Grid_Wide))) {
  98.         if ((y >= Grafs.Double_Y) && (y <= (Grafs.Double_Y + Grafs.Grid_High))) {
  99.             /* Mouse clicked inside double button */
  100.             return (TRUE) ;
  101.         }
  102.     }
  103.     return (FALSE) ;
  104. }
  105.  
  106. /*************************************************************************/
  107.  
  108. boolean Computer_Doubles (Player_t Comp, Layout_t Curr_Lay[2])
  109. /*
  110. PURPOSE: To see if the computer wants to double
  111. */
  112. {
  113.     short    My_Pips,His_Pips ; /* Positive is good for the player */
  114.     short    His_Pieces,My_Pieces ;
  115.     double   My_Throws,His_Throws ;
  116.     long     My_Est,His_Est ;
  117.     Player_t Opp ;
  118.     extern Stats_t Statistics[N_PLAYERS] ;
  119.  
  120.     if (!Can_Double(Comp)) {
  121.         return (FALSE) ;
  122.     }
  123.  
  124.     Opp = OPPONENT (Comp) ;
  125.  
  126.     /*
  127.      * Don't bother doubling if you'd win anyway without it.
  128.      */
  129.     if (Statistics[Comp].Games_Won == (Target_Score-1)) {
  130.         return (FALSE) ;
  131.     }
  132.  
  133.     /*
  134.      * Don't double if only a few pieces left on the board, too
  135.      * complicated and subtle a problem for a poor computer.
  136.      */
  137.     if (Total_Pieces_On_Board (Curr_Lay[Comp],Curr_Lay[Opp]) < 12) {
  138.         return (FALSE) ;
  139.     }
  140.  
  141.     if (!Overlap(Curr_Lay[Comp],Curr_Lay[Opp])) {
  142.         /*
  143.          * There is no overlap, so a basic piece and pip count
  144.          * analysis is sufficient
  145.          */
  146.  
  147.         My_Pips    = Pip_Count (Curr_Lay[Comp]) ;
  148.         His_Pips   = Pip_Count (Curr_Lay[Opp]) ;
  149.         My_Throws  = (My_Pips / Pips_Per_Throw) - 1 ;
  150.         His_Throws = (His_Pips / Pips_Per_Throw) ;
  151.  
  152.         if (My_Throws <= (His_Throws/2.0)) {
  153.             /*
  154.              * May be worth doubling because I have double the chance of
  155.              * reaching home before him.
  156.              */
  157.             My_Pieces  = Pieces_On_Board (Curr_Lay[Comp]) ;
  158.             His_Pieces = Pieces_On_Board (Curr_Lay[Opp]) ;
  159.             if (His_Pieces < My_Pieces) {
  160.                 return (FALSE) ;  /* He has less pieces to take off */
  161.             } else {
  162.                 return (TRUE) ;
  163.             }
  164.         } else {
  165.             return (FALSE) ;
  166.         }
  167.     }
  168.  
  169.     /*
  170.      * I am losing, he is within one game of winning, double out
  171.      * of desperation...
  172.      */
  173.     if ((Statistics[Opp].Games_Won == (Target_Score-1)) &&
  174.         (Statistics[Comp].Games_Won <  (Target_Score-1))) {
  175.         return (TRUE) ;
  176.     }
  177.  
  178.     /*
  179.      * Look at my view of my changes of winning...
  180.      */
  181.     My_Est  = Evaluate_Move (Curr_Lay[Comp],Curr_Lay[Opp],Comp) ;
  182.  
  183.     /*
  184.      * Look at my view of his chances of winning...
  185.      */
  186.     His_Est = Evaluate_Move (Curr_Lay[Opp],Curr_Lay[Comp],Comp) ;
  187.     if (My_Est > (His_Est*2)) {
  188.         return (TRUE) ;
  189.     } else {
  190.         return (FALSE) ;
  191.     }
  192. }
  193.  
  194. /*************************************************************************/
  195.  
  196. boolean Human_Rejects_Double (void)
  197. /*
  198. PURPOSE: To return TRUE if the Human rejects the double.
  199. */
  200. {
  201.     short User_Input,x,y ;
  202.     boolean Finished ;
  203.     extern boolean F10_Hit ;
  204.  
  205.     Print_Message (ACC_DBL_MSG) ;
  206.     Show_Mouse_Cursor () ;
  207.     Set_Cursor_Shape (QUESTION_SHP,0,0) ;
  208.  
  209.     do {
  210.         User_Input = Get_Mouse_Or_Key (&x,&y) ;
  211.         if (User_Input & (LEFT_BIT | RIGHT_BIT)) {
  212.             Finished = TRUE ;
  213.         } else if (User_Input & FUN_BIT) {
  214.            if ((User_Input & CHAR_MASK) == F10_KEY) {
  215.                F10_Hit = TRUE ;
  216.                return (FALSE) ;
  217.            }
  218.        }
  219.     } while (!Finished) ;
  220.  
  221.     Hide_Mouse_Cursor () ;
  222.  
  223.     if (Selected_Double_Button (x,y)) {
  224.         return (FALSE) ;
  225.     } else {
  226.         return (TRUE) ;
  227.     }
  228. }
  229.  
  230. /*************************************************************************/
  231.  
  232. boolean Computer_Rejects_Double (Player_t Comp, Layout_t Curr_Lay[2])
  233. /*
  234. PURPOSE: To see if the computer rejects a double in these circs.
  235. */
  236. {
  237.     short    My_Pips,His_Pips ; /* Positive is good for the player */
  238.     long     My_Est,His_Est ;
  239.     double   My_Throws,His_Throws ;
  240.     Player_t Opp ;
  241.     extern   Stats_t Statistics[N_PLAYERS] ;
  242.     extern   int Target_Score ;
  243.  
  244.     Opp = OPPONENT(Comp) ;
  245.  
  246.     /*
  247.      * Don't refuse if, by refusing, you'd lose the whole match.
  248.      */
  249.     if (Statistics[Opp].Games_Won == (Target_Score-1)) {
  250.         return (FALSE) ; /* Don't refuse */
  251.     }
  252.  
  253.     /*
  254.      * Don't refuse if we are just at the start of the game
  255.      */
  256.     if (N_Moves < 10) {
  257.         return (FALSE) ;
  258.     }
  259.  
  260.     My_Pips    = Pip_Count (Curr_Lay[Comp]) ;
  261.     His_Pips   = Pip_Count (Curr_Lay[Opp]) ;
  262.     My_Throws  = (My_Pips / Pips_Per_Throw)  ;
  263.     His_Throws = (His_Pips / Pips_Per_Throw) - 1.0 ;
  264.  
  265.     if (My_Throws < His_Throws) {
  266.         /* I would win on a pure pip-count, so... */
  267.         /*
  268.          * Look at my view of my changes of winning...
  269.          */
  270.         My_Est  = Evaluate_Move (Curr_Lay[Comp],Curr_Lay[Opp],Comp) ;
  271.         /*
  272.          * Look at my view of his chances of winning...
  273.          */
  274.         His_Est = Evaluate_Move (Curr_Lay[Opp],Curr_Lay[Comp],Comp) ;
  275.         if (My_Est > His_Est) {
  276.             return (FALSE) ; /* Don't reject, accept */
  277.         } else {
  278.             return (TRUE) ;
  279.         }
  280.     } else {
  281.         if ((My_Pips > 100) && (His_Pips > 100)) {
  282.             return (FALSE) ; /* Early in game, don't reject */
  283.         } else {
  284.             return (TRUE) ;
  285.         }
  286.     }
  287. }
  288.  
  289. /*************************************************************************/
  290.  
  291.